import { Request, Response } from 'express';
import { NginxUtil } from '../utils/nginx.util';
import fs from 'fs/promises';
import { existsSync } from 'fs';
import path from 'path';
import { ConfigModel } from '../models/Config';
import { exec } from 'child_process';
import { promisify } from 'util';
import { access } from 'fs/promises';
import { constants } from 'fs';

const execAsync = promisify(exec);

export class NginxController {

  static async getNginxVersion(req: Request, res: Response) {
    const version = await NginxUtil.getNginxVersion();
    res.json({ version });
  }

  // 获取所有配置文件列表
  static async getAllConfigs(req: Request, res: Response) {
    try {
      const configs = await NginxUtil.getAllConfigs();
      res.json(configs); 
    } catch (error) {
      res.status(500).json({ message: (error as Error).message });
    }
  }

  // 获取主配置文件
  static async getMainConfig(req: Request, res: Response) {
    try {
      const config = await NginxUtil.getMainConfig();
      if (!config) {
        return res.status(404).json({ message: '主配置文件不存在' });
      }
      res.json(config);
    } catch (error) {
      res.status(500).json({ message: '获取主配置文件失败' });
    }
  }

  // 创建新配置文件
  static async createConfig(req: Request, res: Response) {
    try {
      const { name, content } = req.body;
      if (!name || !content) {
        return res.status(400).json({ message: '配置名称和内容不能为空' });
      }

      if (!existsSync(NginxUtil.nginxConfdDir)) {
        await fs.mkdir(NginxUtil.nginxConfdDir, { recursive: true });
      }

      const configPath = path.join(NginxUtil.nginxConfdDir, `${name}.conf`);
      await fs.writeFile(configPath, content, 'utf8');

      const newConfig = {
        name,
        content,
        file_path: configPath
      };

      res.status(201).json(newConfig);
    } catch (error) {
      console.log(error);
      res.status(500).json({ message: '创建配置失败' });
    }
  }

  // 更新配置文件
  static async updateConfig(req: Request, res: Response) {
    try {
      const { content } = req.body;
      const { filePath } = req.params;
      
      if (!filePath || !content) {
        return res.status(400).json({ message: '配置文件路径和内容不能为空' });
      }

      if(!existsSync(filePath)) {
        const isDocker = NginxUtil.isDockerized;
        if (isDocker) {
          return res.status(400).json({ message: 'docker 模式下配置文件不存在, 请确保该文件是否映射到宿主机' });
        }
        return res.status(400).json({ message: '配置文件不存在' });
      }

      await fs.writeFile(filePath, content, 'utf8');

      res.json({ message: '配置更新成功' });
    } catch (error) {
      console.error('更新配置失败:', error);
      res.status(500).json({ message: '更新配置失败' });
    }
  }

  // 删除配置文件
  static async deleteConfig(req: Request, res: Response) {
    try {
      const { filePath } = req.params;
      console.log('filePath', filePath);
      await fs.unlink(filePath);
      res.json({ message: '配置删除成功' });
    } catch (error) {
      res.status(500).json({ message: '删除配置失败' });
    }
  }

  // 测试配置
  static async testConfig(req: Request, res: Response) {
    try {
      await NginxUtil.testConfig();
      res.json({ message: '配置验证通过' });
    } catch (error) {
      res.status(400).json({ message: (error as Error).message });
    }
  }

  // 应用配置（重新加载Nginx）
  static async reloadConfig(req: Request, res: Response) {
    try {
      await NginxUtil.reloadConfig();
      res.json({ message: '配置已成功应用' });
    } catch (error) {
      res.status(500).json({ message: (error as Error).message });
    }
  }

  // 获取系统配置
  static async getSystemConfig(req: Request, res: Response) {
    try {
      const config = await ConfigModel.getSystemConfig();
      res.json(config);
    } catch (error) {
      console.error('Failed to get system config:', error);
      res.status(500).json({ message: '获取系统配置失败' });
    }
  }

  // 更新系统配置
  static async updateSystemConfig(req: Request, res: Response) {
    try {
      const config = req.body;
      await ConfigModel.updateSystemConfig(config);
      
      // 更新环境变量
      if (config.nginxExec) {
        process.env.NGINX_EXEC = config.nginxExec;
      }
      if (config.nginxCwd) {
        process.env.NGINX_CWD = config.nginxCwd;
      }
      if (config.nginxConfDir) {
        process.env.NGINX_CONF_DIR = config.nginxConfDir;
      }
      await NginxUtil.updateEnv();

      res.json({ message: '系统配置更新成功' });
    } catch (error) {
      console.error('Failed to update system config:', error);
      res.status(500).json({ message: '更新系统配置失败' });
    }
  }

  // 测试 Nginx 可执行文件
  static async testNginxExec(req: Request, res: Response) {
    try {
      const { path: nginxPath } = req.body;
      
      // 检查文件是否存在且可执行
      try {
        await access(nginxPath, constants.X_OK);
      } catch (error) {
        return res.status(400).json({ message: 'Nginx 可执行文件不存在或无执行权限' });
      }

      // 测试版本命令
      const { stdout, stderr } = await execAsync(`${nginxPath} -v`);
      // Nginx 的版本信息输出在 stderr 中
      const version = stderr || stdout;
      res.json({ message: `Nginx 可执行文件测试成功: ${version.trim()}` });
    } catch (error) {
      console.error('Failed to test nginx executable:', error);
      res.status(500).json({ message: 'Nginx 可执行文件测试失败' });
    }
  }

  // 测试配置目录
  static async testConfDir(req: Request, res: Response) {
    try {
      const { path: confDir } = req.body;
      
      // 检查目录是否存在且可读写
      try {
        await access(confDir, constants.R_OK | constants.W_OK);
      } catch (error) {
        return res.status(400).json({ message: '配置目录不存在或无读写权限' });
      }

      // 检查是否包含 .conf 文件
      const { stdout } = await execAsync(`find "${confDir}" -name "*.conf" | wc -l`);
      const confCount = parseInt(stdout.trim());
      
      res.json({ 
        message: `配置目录测试成功，包含 ${confCount} 个配置文件`,
        confCount 
      });
    } catch (error) {
      console.error('Failed to test conf directory:', error);
      res.status(500).json({ message: '配置目录测试失败' });
    }
  }

  // 测试 Docker 容器
  static async testDockerContainer(req: Request, res: Response) {
    try {
      const { name } = req.body;
      
      // 检查 Docker 容器是否存在且运行中
      const { stdout, stderr } = await execAsync(`docker container inspect ${name}`);
      const containerInfo = JSON.parse(stdout);
      
      if (!containerInfo || !containerInfo[0]) {
        return res.status(400).json({ message: '容器不存在' });
      }

      const state = containerInfo[0].State;
      if (!state.Running) {
        return res.status(400).json({ message: '容器未运行' });
      }

      const { stdout: stdout1, stderr: stderr1 } = await execAsync(`docker exec ${name} nginx -v`);
      const version = stderr1 || stdout1;
      console.log(version);

      res.json({
        message: `容器测试成功: ${version.trim()}`,
        status: state.Status,
        startedAt: state.StartedAt
      });
    } catch (error) {
      console.error('Failed to test docker container:', error);
      res.status(500).json({ message: 'Docker 容器测试失败' });
    }
  }
} 